from feed_forward.backpropagation import Backpropagation
from feed_forward.feed_forward_network import FeedforwardNetwork
from feed_forward.feedforward_layer import FeedforwardLayer
from util.training_set import TrainingSet

__author__ = 'Douglas'

training_set = TrainingSet()

training_set.append([1.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 1.0])  # A
training_set.append([1.0, 0.0, 1.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 1.0, 0.0])  # B
training_set.append([1.0, 1.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 1.0, 1.0])  # C
training_set.append([1.0, 1.0, 0.0, 1.0, 0.0, 0.0], [0.0, 0.0, 1.0, 0.0, 0.0])  # D
training_set.append([1.0, 0.0, 0.0, 1.0, 0.0, 0.0], [0.0, 0.0, 1.0, 0.0, 1.0])  # E
training_set.append([1.0, 1.0, 1.0, 0.0, 0.0, 0.0], [0.0, 0.0, 1.0, 1.0, 0.0])  # F
training_set.append([1.0, 1.0, 1.0, 1.0, 0.0, 0.0], [0.0, 0.0, 1.0, 1.0, 1.0])  # G
training_set.append([1.0, 0.0, 1.0, 1.0, 0.0, 0.0], [0.0, 1.0, 0.0, 0.0, 0.0])  # H
training_set.append([0.0, 1.0, 1.0, 0.0, 0.0, 0.0], [0.0, 1.0, 0.0, 0.0, 1.0])  # I
training_set.append([0.0, 1.0, 1.0, 1.0, 0.0, 0.0], [0.0, 1.0, 0.0, 1.0, 0.0])  # J
training_set.append([1.0, 0.0, 0.0, 0.0, 1.0, 0.0], [0.0, 1.0, 0.0, 1.0, 1.0])  # K
training_set.append([1.0, 0.0, 1.0, 0.0, 1.0, 0.0], [0.0, 1.0, 1.0, 0.0, 0.0])  # L
training_set.append([1.0, 1.0, 0.0, 0.0, 1.0, 0.0], [0.0, 1.0, 1.0, 0.0, 1.0])  # M
training_set.append([1.0, 1.0, 0.0, 1.0, 1.0, 0.0], [0.0, 1.0, 1.0, 1.0, 0.0])  # N
training_set.append([1.0, 0.0, 0.0, 1.0, 1.0, 0.0], [0.0, 1.0, 1.0, 1.0, 1.0])  # O
training_set.append([1.0, 1.0, 1.0, 0.0, 1.0, 0.0], [1.0, 0.0, 0.0, 0.0, 0.0])  # P
training_set.append([1.0, 1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 0.0, 0.0, 0.0, 1.0])  # Q
training_set.append([1.0, 0.0, 1.0, 1.0, 1.0, 0.0], [1.0, 0.0, 0.0, 1.0, 0.0])  # R
training_set.append([0.0, 1.0, 1.0, 0.0, 1.0, 0.0], [1.0, 0.0, 0.0, 1.0, 1.0])  # S
training_set.append([0.0, 1.0, 1.0, 1.0, 1.0, 0.0], [1.0, 0.0, 1.0, 0.0, 0.0])  # T
training_set.append([1.0, 0.0, 0.0, 0.0, 1.0, 1.0], [1.0, 0.0, 1.0, 0.0, 1.0])  # U
training_set.append([1.0, 0.0, 1.0, 0.0, 1.0, 1.0], [1.0, 0.0, 1.0, 1.0, 0.0])  # V
training_set.append([0.0, 1.0, 1.0, 1.0, 1.0, 0.0], [1.0, 0.0, 1.0, 1.0, 1.0])  # W
training_set.append([1.0, 1.0, 0.0, 0.0, 1.0, 1.0], [1.0, 1.0, 0.0, 0.0, 0.0])  # X
training_set.append([1.0, 1.0, 0.0, 1.0, 1.0, 1.0], [1.0, 1.0, 0.0, 0.0, 1.0])  # Y
training_set.append([1.0, 0.0, 0.0, 1.0, 1.0, 1.0], [1.0, 1.0, 0.0, 1.0, 0.0])  # Z

network = FeedforwardNetwork()

network.add_layer(FeedforwardLayer(6))
network.add_layer(FeedforwardLayer(6))
network.add_layer(FeedforwardLayer(5))

network.reset()

train = Backpropagation(network, training_set, 0.2, 0.7)

for epoch in range(1, 5001):
    train.iteration()
    print("Epoch #", epoch, "Error:", train.error)

    if train.error <= 0.001:
        break

print("Result:")

for row in training_set:
    actual = network.compute_outputs(row.input_pattern)
    print(row.input_pattern, "actual=", actual, "ideal=", row.ideal_output)